<?php
declare(strict_types=1);

namespace SixShop\MakerBundle\Generator;

use Symfony\Component\Console\Style\SymfonyStyle;

class ModelGenerator
{
    private string $templatesPath;

    public function __construct()
    {
        $this->templatesPath = __DIR__ . '/../../templates';
    }

    /**
     * Generate model file
     */
    public function generateModel(
        string $tableName, 
        string $tableComment, 
        array $fields, 
        array $extensionInfo, 
        string $targetPath, 
        SymfonyStyle $io
    ): bool {
        try {
            $modelName = $this->generateModelName($tableName);
            $modelPath = $targetPath . '/src/Model';
            
            // Ensure model directory exists
            if (!is_dir($modelPath)) {
                if (!mkdir($modelPath, 0755, true)) {
                    $io->error("无法创建模型目录: {$modelPath}");
                    return false;
                }
            }
            
            $fileName = $modelName . '.php';
            $filePath = $modelPath . '/' . $fileName;
            
            // Check if file exists
            if (file_exists($filePath)) {
                if (!$io->confirm("模型文件已存在: {$fileName}，是否覆盖?", false)) {
                    $io->text("跳过模型文件: {$fileName}");
                    return true;
                }
            }
            
            // Prepare template variables
            $namespace = rtrim($extensionInfo['namespace'], '\\') . '\\';
            $fillableFields = $this->getFillableFields($fields);
            $requiredFields = $this->getRequiredFields($fields);
            $relationshipFields = $this->getRelationshipFields($fields);
            
            // Generate content using template
            ob_start();
            include $this->templatesPath . '/src/Model/Model.php.tpl.php';
            $content = ob_get_clean();
            
            // Write file
            if (file_put_contents($filePath, $content) !== false) {
                $io->text("✓ 生成模型文件: src/Model/{$fileName}");
                return true;
            } else {
                $io->error("✗ 无法写入模型文件: {$fileName}");
                return false;
            }
            
        } catch (\Exception $e) {
            $io->error('生成模型文件时发生错误: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Generate model class name from table name
     */
    private function generateModelName(string $tableName): string
    {
        // Remove common prefixes
        $tableName = preg_replace('/^(tbl_|tb_|t_)/', '', $tableName);
        
        // Convert to PascalCase
        $parts = explode('_', $tableName);
        $parts = array_map('ucfirst', $parts);
        
        return implode('', $parts) . 'Model';
    }
    
    /**
     * Generate model class name for relationships (without Model suffix)
     */
    private function generateModelNameForRelation(string $tableName): string
    {
        // Remove common prefixes
        $tableName = preg_replace('/^(tbl_|tb_|t_)/', '', $tableName);
        
        // Convert to PascalCase
        $parts = explode('_', $tableName);
        $parts = array_map('ucfirst', $parts);
        
        return implode('', $parts) . 'Model';
    }
    
    /**
     * Get fillable fields (excluding auto-generated fields)
     */
    private function getFillableFields(array $fields): array
    {
        $fillable = [];
        $excludeFields = ['id', 'create_time', 'update_time', 'delete_time'];
        
        foreach ($fields as $field) {
            if (!in_array($field['name'], $excludeFields)) {
                $fillable[] = $field['name'];
            }
        }
        
        return $fillable;
    }
    
    /**
     * Get required fields for validation
     */
    private function getRequiredFields(array $fields): array
    {
        $required = [];
        $excludeFields = ['id', 'create_time', 'update_time', 'delete_time'];
        
        foreach ($fields as $field) {
            if (!in_array($field['name'], $excludeFields) && 
                (!isset($field['null']) || !$field['null'])) {
                $required[] = $field;
            }
        }
        
        return $required;
    }
    
    /**
     * Get relationship fields (foreign keys)
     */
    private function getRelationshipFields(array $fields): array
    {
        $relationships = [];
        
        foreach ($fields as $field) {
            if (str_ends_with($field['name'], '_id') && $field['name'] !== 'id') {
                $relationName = str_replace('_id', '', $field['name']);
                $modelName = $this->generateModelNameForRelation($relationName);
                
                $relationships[] = [
                    'method' => $relationName,
                    'model' => $modelName,
                    'foreign_key' => $field['name'],
                    'local_key' => 'id',
                    'comment' => $field['comment'] ?? "关联到{$modelName}"
                ];
            }
        }
        
        return $relationships;
    }
}